import {toast, alert, showLoading, hideLoading} from '@/utils/wxapi.js'
import store from '@/store/globalStore.js'
/* ------------------- 蓝牙模块 ------------------- */
/**
 * 流程：
 * 1.先初始化蓝牙适配器，
 * 2.获取本机蓝牙适配器的状态，
 * 3.开始搜索，当停止搜索以后在开始搜索，就会触发蓝牙是配置状态变化的事件，
 * 4.搜索完成以后获取所有已经发现的蓝牙设备，就可以将devices中的设备Array取出来，
 * 5.然后就可以得到所有已经连接的设备了
 */
// import {BLisOpen} from '@/utils/bluetooth.js'
export {
  // 初始化蓝牙模块
  openBTAdapter,
  // 断开蓝牙模块
  closeBTAdapter,
  // 监听适配器状态变化
  onListernerBTState,
  // 获取蓝牙适配状态
  getBTAdapterState,
  // 开始搜寻附近设备
  startDisBTDev,
  // 监听寻找到的新设备
  onListenerBTDevFound,
  // 停止搜寻附近设备
  stopDisBisBTDev,
  // 连接低功耗蓝牙设备
  connectBLEDev,
  // 断开BTE连接
  closeConnectBLEDev,
  // 监听低功耗蓝牙状态的改变
  listenerBLEConnectionState
}

// 蓝牙适配状态
const BTStatus = {
  10000: '未初始化蓝牙适配器',
  10001: '当前蓝牙适配器不可用',
  10002: '没有找到指定设备',
  10003: '连接失败',
  10004: '没有找到指定服务',
  10005: '没有找到指定特征值',
  10006: '当前连接已断开',
  10007: '当前特征值不支持此操作',
  10008: '其余所有系统上报的异常',
  10009: '系统版本低于 4.3 不支持 BLE'
}

// 初始化蓝牙适配，蓝牙相关的api必须在初始化后调用
function openBTAdapter () {
  return new Promise((resolve, reject) => {
    wx.openBluetoothAdapter({
      success: res => {
        console.log(res)
        // 0: '正常'
        resolve(res.errCode)
      },
      fail: err => {
        console.log('初始化蓝牙模块失败', err)
        reject(BTStatus[err.errCode])
      }
    })
  })
}

// 关闭蓝牙模块。断开所有连接释放系统资源
function closeBTAdapter () {
  return new Promise((resolve, reject) => {
    wx.closeBluetoothAdapter({
      success: res => {
        // console.log(res)
        // 0: '正常'
        resolve(res.errCode)
      },
      fail: err => {
        console.log('关闭蓝牙模块失败', err)
        reject(BTStatus[err.errCode])
      }
    })
  })
}

// 初始化的时候监听蓝牙适配器状态变化
function onListernerBTState (fn) {
  wx.onBluetoothAdapterStateChange(res => {
    // res.available 蓝牙适配器是否可用
    // res.discovering 是否处于搜索状态
    console.log(res)
    fn(res)
  })
}

// 获取本机蓝牙适配器状态
function getBTAdapterState (fn) {
  return new Promise((resolve, reject) => {
    wx.getBluetoothAdapterState({
      success: res => {
        resolve(res)
      },
      fail: err => {
        console.log('获取适配器状态失败' + err)
        reject(BTStatus[err.errCode])
      }
    })
  })
}

// 开始搜寻附近的蓝牙设备
// 注意，该操作比较耗费系统资源，请在搜索并连接到设备后调用 stop 方法停止搜索。
function startDisBTDev () {
  return new Promise((resolve, reject) => {
    wx.startBluetoothDevicesDiscovery({
      // services: ['FEE7'] uuid列表
      // interval: 500, // 间隔500毫秒
      allowDuplicatesKey: true, // 允许重复上报， RSSI不同
      success: res => {
        resolve(res)
      },
      fail: err => {
        console.log('开始搜索失败' + err)
        reject(BTStatus[err.errCode])
      }
    })
  })
}

/*
{devices: [
{
  name 蓝牙设备名称，某些设备可能没有
  deviceId 用于区分设备的 id
  RSSI 当前蓝牙设备的信号强度
  advertisData 当前蓝牙设备的广播数据段中的 ManufacturerData 数据段。
  advertisServiceUUIDs 当前蓝牙设备的广播数据段中的 ServiceUUIDs 数据段
  localName 当前蓝牙设备的广播数据段中的 LocalName 数据段
  serviceData 当前蓝牙设备的广播数据段中的 ServiceData 数据段
}
]}
若在 wx.onBluetoothDeviceFound 回调了某个设备，则此设备会添加到 wx.getBluetoothDevices 接口获取到的数组中。
*/

// 监听寻找到新设备事件
function onListenerBTDevFound (that) {
  wx.onBluetoothDeviceFound(res => {
    // console.log(res)
    let dev = res.devices[0]
    // name和localName都存在
    if (dev.name && dev.localName) {
      let arr = that.devData.filter(item => item.deviceId === dev.deviceId)
      if (arr.length > 0) {
        // 说明存在相同设备，要进行RSSI更新
        let n = that.devData.indexOf(arr[0])
        // 转换信号
        let rssi = Math.floor(max(0, dev.RSSI + 100) / 10)
        if (rssi <= 0) {
          // 无信号删除
          that.devData.splice(n, 1)
        } else {
          // 有信号更新
          that.devData[n].RSSI = rssi
        }
      } else {
        // 新设备，直接push
        that.devData.push(dev)
      }
    }
    // console.log(that.devData)
  })
}

function max (n1, n2) {
  return Math.max(n1, n2)
}

// function inArray (arr, key, val) {
//   for (let i = 0; i < arr.length; i++) {
//     if (arr[i][key] === val) {
//       return i
//     }
//   }
//   return -1
// }

// 停止搜寻附近的蓝牙设备
function stopDisBisBTDev () {
  wx.stopBluetoothDevicesDiscovery({
    success (res) {
      console.log('停止搜索', res)
    }
  })
}

// 连接低功耗蓝牙设备
function connectBLEDev (deviceId, fn) {
  // 判断是否有连接设备，如果有先断开再连接
  if (store.state.BTEDevId) {
    closeConnectBLEDev(store.state.BTEDevId, 'quick', () => {
      connectBLEDev(deviceId, fn)
    })
  } else {
    showLoading('连接中...')
    wx.createBLEConnection({
      deviceId,
      success: res => {
        hideLoading()
        // 连接成功
        console.log('连接成功', res)
        alert('连接成功')
        // 存到global中
        store.commit('commitChangeBTStatus', deviceId)
        // 获取蓝牙设备所有服务
        getBLEDevSercices(deviceId)
        // 监听BLE的连接状态
        fn && fn()
      },
      fail: err => {
        hideLoading()
        console.log(err)
        alert(BTStatus[err.errCode])
        // 断开BLE链接
        closeConnectBLEDev(deviceId)
        store.commit('commitChangeBTStatus', '')
      }
    })
  }
  // 停止搜索
  stopDisBisBTDev()
}

/*
services: Array(6)
  0: {uuid: "49535343-FE7D-4AE5-8FA9-9FAFD205E455", isPrimary: true}
  1: {uuid: "000018F0-0000-1000-8000-00805F9B34FB", isPrimary: true}
  2: {uuid: "E7810A71-73AE-499D-8C15-FAA9AEF0C3F2", isPrimary: true}
  3: {uuid: "0000180A-0000-1000-8000-00805F9B34FB", isPrimary: true}
  4: {uuid: "00001800-0000-1000-8000-00805F9B34FB", isPrimary: true}
  5: {uuid: "00001801-0000-1000-8000-00805F9B34FB", isPrimary: true}
*/

// 获取蓝牙设备所有服务
function getBLEDevSercices (deviceId) {
  wx.getBLEDeviceServices({
    deviceId,
    success: res => {
      console.log('获取的服务', res)
      // res.services
      // 获取特征值,找到 read write notify都支持的特征
      res.services.forEach(item => {
        getBLEDevCharact(deviceId, item.uuid)
      })
    }
  })
}

/*
characteristics:Array(1)
  0: {
    properties:v {read: true, write: true, notify: true, indicate: true}
    uuid: "BEF8D6C9-9C21-4C9E-B632-BD58C1009F9F"
  }
*/

// 获取特征值
function getBLEDevCharact (deviceId, serviceId) {
  let json = {
    deviceId,
    serviceId
  }
  wx.getBLEDeviceCharacteristics({
    deviceId,
    serviceId,
    success: res => {
      console.log('得到的特征值', res)
      // res.characteristics 数组
      // 找到 read write notify 的服务
      res.characteristics.forEach(item => {
        if (item.properties.read && item.properties.write && item.properties.notify) {
          // 找到需要的特征
          json.uuid = item.uuid
          store.commit('commitBTDevCharact', json)
        }
      })
      console.log('设备读写特这值', store.state.BTDevCharact)
    }
  })
}

// 断开与BLE的连接
// type 用来标识是否启用loading
function closeConnectBLEDev (deviceId, type, fn) {
  console.log(type)
  if (type !== 'quick') { showLoading('断开中...') }
  wx.closeBLEConnection({
    deviceId,
    success: () => {
      if (type !== 'quick') { hideLoading() }
      // 成功
      if (type !== 'quick') { toast('当前连接设备已断开') }
      // 删除global
      store.commit('commitChangeBTStatus', '')
      fn && fn()
    },
    fail: err => {
      if (type !== 'quick') { hideLoading() }
      console.log(err)
      if (type !== 'quick') { alert(BTStatus[err.errCode]) }
      store.commit('commitChangeBTStatus', '')
    }
  })
}

// 监听低功耗蓝牙连接状态的改变
function listenerBLEConnectionState (deviceId) {
  wx.onBLEConnectionStateChange(res => {
    // res.deviceId
    // res.connected
    console.log('低功耗蓝牙连接状态', res)
    if (!res.connected) {
      closeConnectBLEDev(deviceId)
      store.commit('commitChangeBTStatus', '')
    }
  })
}
